package orm

import (
	"animal/octopus/common"
	"animal/octopus/model"

	log "github.com/sirupsen/logrus"
	"gorm.io/gorm"
)

// ------------------------------------------------------------------------------
//
// ------------------------------------------------------------------------------
func GetReportRuleList(db *gorm.DB, moduleID uint) ([]common.ReportRuleInfo, error) {
	var infos []common.ReportRuleInfo

	var rules []model.ReportRule
	if err := common.DB(db).Find(&rules, "module_id = ?", moduleID).Error; err != nil {
		log.Error("find topo view failed")
		return nil, err
	}

	for _, rule := range rules {
		module, ok := common.FindItemByID[model.Module](db, rule.Parent)
		if !ok {
			log.WithField("parent", rule.Parent).Error("find parent failed")
			return nil, common.NewErrCode(common.ErrGeneralError)
		}

		ruleInfo := common.ReportRuleInfo{
			RuleID:     rule.ID,
			ModuleID:   rule.ModuleID,
			Desc:       rule.Desc,
			MatchType:  rule.MatchType,
			MatchRule:  rule.MatchRule,
			ParentId:   module.ID,
			ParentName: module.Name,
			CreateTime: common.TimeFormat(rule.Model.CreatedAt),
		}

		infos = append(infos, ruleInfo)
	}

	return infos, nil
}

// ------------------------------------------------------------------------------
//
// ------------------------------------------------------------------------------
func CreateReportRule(db *gorm.DB, param common.CreateReportRuleParam) (uint, error) {
	module, ok := common.FindItemByName[model.Module](db, param.Parent)
	if !ok {
		log.WithField("parent", param.Parent).Error("find parent failed")
		return 0, common.NewErrCode(common.ErrGeneralError)
	}

	rule := model.ReportRule{
		Desc:      param.Desc,
		MatchType: param.MatchType,
		MatchRule: param.MatchRule,
		Parent:    module.ID,
		ModuleID:  param.ModuleID,
	}

	if err := common.DB(db).Create(&rule).Error; err != nil {
		log.Error("create report rule failed")
		return 0, err
	}

	log.Info("create report rule success")

	return rule.ID, nil
}

// ------------------------------------------------------------------------------
//
// ------------------------------------------------------------------------------
func EditReportRule(db *gorm.DB, param common.EditReportRuleParam) error {
	rule, ok := common.FindItemByID[model.ReportRule](db, param.RuleID)
	if !ok {
		log.WithField("rule", param.RuleID).Error("find rule failed")
		return common.NewErrCode(common.ErrGeneralError)
	}

	module, ok := common.FindItemByName[model.Module](db, param.Parent)
	if !ok {
		log.WithField("parent", param.Parent).Error("find parent failed")
		return common.NewErrCode(common.ErrGeneralError)
	}

	rule.Desc = param.Desc
	rule.MatchType = param.MatchType
	rule.MatchRule = param.MatchRule
	rule.Parent = module.ID

	if err := common.DB(db).Save(&rule).Error; err != nil {
		log.Error("edit report rule failed")
		return err
	}

	return nil
}

// ------------------------------------------------------------------------------
//
// ------------------------------------------------------------------------------
func DeleteReportRule(db *gorm.DB, param common.DeleteReportRuleParam) error {
	if err := common.DB(db).Where("id = ?", param.RuleID).Unscoped().
		Delete(&model.ReportRule{}).Error; err != nil {
		log.WithFields(log.Fields{
			"rule":  param.RuleID,
			"error": err,
		}).Error("delete report rule failed")
		return common.NewErrCode(common.ErrDatabaseError)
	}
	return nil
}
